﻿using System.Text;
using System.Text.Json;

namespace Net6Template.Tools
{
    public static class ExtensionMethod
    {
        public static bool IsNullOrEmpty<T>(this IEnumerable<T> list) => list == null || !list.Any();

        public static string ToJson<T>(this T obj) => JsonSerializer.Serialize(obj);

        public static T ToObject<T>(this string json) => JsonSerializer.Deserialize<T>(json);

        public static IQueryable<T> GetPaged<T>(this IQueryable<T> objlist, int pageIndex, int pageSize) where T : class
            => objlist.Skip((pageIndex - 1) * pageSize).Take(pageSize).AsQueryable();

        public static IEnumerable<T> GetPaged<T>(this IEnumerable<T> objlist, int pageIndex, int pageSize) where T : class
            => objlist.Skip((pageIndex - 1) * pageSize).Take(pageSize);

        private static readonly object _lock = new object();

        /// <summary>
        /// 生成随即订单号
        /// </summary>
        /// <returns></returns>
        public static string GetOrderNumber()
        {
            lock (_lock)
            {
                Random ran = new();
                return $"FX{DateTime.Now:yyyyMMddHHmmssfff}{ran.Next(100, 999)}";
            }
        }

        public static string CreateRandStrCode(int length, int seed = 0)
        {
            string basecode = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
            //Guid的哈希码作为种子值
            byte[] buffer = Guid.NewGuid().ToByteArray();
            var ranInt = BitConverter.ToInt32(buffer, 0) + seed;

            Random random = new Random(ranInt);
            string re = "";
            for (int i = 0; i < length; i++)
            {
                int number = random.Next(basecode.Length);
                re += basecode.Substring(number, 1);
            }
            return re;
        }
        public static string CreateRandStrCode(int length = 1)
        {
            string basecode = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

            Random random = new Random();
            string re = "";
            for (int i = 0; i < length; i++)
            {
                int number = random.Next(basecode.Length);
                re += basecode.Substring(number, 1);
            }
            return re;
        }
        public static string CreateUserInviteCode(int id)
        {
            var basecode = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
            try
            {
                int[] array = new int[6];
                int i = 0;

                while (id > 0)
                {
                    int a = id % 32;
                    array[i++] = a;
                    id = id / 32;
                }

                StringBuilder result = new StringBuilder();
                for (int j = array.Length - 1; j >= 0; j--)
                {
                    result.Append(basecode.Substring(array[j], 1));
                }


                return result.ToString();


            }

            catch
            {

                return CreateRandStrCode(6);
            }


        }

        public static string SetUserInviteCode(int id)
        {
            var basecode = "ABCDEFGHIJKLMNPQRSTUVWXYZ123456789";
            int[] array = new int[6];
            int i = 0;

            while (id > 0)
            {
                int a = id % 34;
                array[i++] = a;
                id = id / 34;
            }

            StringBuilder result = new StringBuilder();
            for (int j = array.Length - 1; j >= 0; j--)
            {
                result.Append(basecode.Substring(array[j], 1));
            }



            return result.ToString();
        }
        /// <summary>
        /// 根据身份证号获取生日
        /// </summary>
        /// <param name="IdCard"></param>
        /// <returns></returns>
        public static DateTime GetBrithdayFromIdCard(this string IdCard)
        {
            DateTime rtn = DateTime.Now;
            if (IdCard.Length == 15)
            {
                rtn = Convert.ToDateTime(IdCard.Substring(6, 6).Insert(4, "-").Insert(2, "-"));
            }
            else if (IdCard.Length == 18)
            {
                rtn = Convert.ToDateTime(IdCard.Substring(6, 8).Insert(6, "-").Insert(4, "-"));
            }
            return rtn;
        }

        /// <summary>
        /// 根据身份证号获取性别
        /// </summary>
        /// <param name="IdCard"></param>
        /// <returns></returns>
        public static string GetGenderFromIdCard(this string IdCard)
        {
            var rtn = "";
            if (IdCard.Length == 15)
            {
                rtn = IdCard.Substring(12, 3);
            }
            else if (IdCard.Length == 18)
            {
                rtn = IdCard.Substring(14, 3);
            }

            if (!string.IsNullOrEmpty(rtn))
            {
                if (int.Parse(rtn) % 2 == 0)//性别代码为偶数是女性奇数为男性
                {
                    return "女";
                }
                else
                {
                    return "男";
                }


            }

            return "";


        }

        public static decimal CalcMaoLi(string yingshou, string lirun)
        {
            try
            {
                var ys = Convert.ToDecimal(yingshou);
                var lr = Convert.ToDecimal(lirun);
                //decimal lr = 0;
                //lr = decimal.TryParse(lirun, out lr) ? lr : 0;
                if (ys == 0 || lr == 0)
                {
                    return 0;
                }
                var maoli = Math.Round((lr / (decimal)ys), 4, MidpointRounding.AwayFromZero);
                return Math.Round(maoli * 100, 2, MidpointRounding.AwayFromZero);
            }
            catch (Exception)
            {
                return 0;
            }

        }
        public static decimal CalcTongBi(string thisYear, string lastYear)
        {
            try
            {
                var thisyear = thisYear.As<decimal>();
                var lastyear = lastYear.As<decimal>();
                if (thisyear == 0 || lastyear == 0)
                {
                    return 0;
                }
                var tongbi = Math.Round(((thisyear - lastyear) / (decimal)lastyear), 4, MidpointRounding.AwayFromZero);
                if (thisyear > lastyear)
                {
                    tongbi = Math.Abs(tongbi);
                }
                else
                {
                    tongbi = -(Math.Abs(tongbi));
                }
                return Math.Round(tongbi * 100, 2, MidpointRounding.AwayFromZero);
            }
            catch (Exception)
            {
                return 0;
            }

        }
        public static decimal CalcHuanBi(string thisQuarter, string lastQuarter)
        {
            var thisquarter = thisQuarter.As<decimal>();
            var lastquarter = lastQuarter.As<decimal>();
            if (thisquarter == 0 || lastquarter == 0)
            {
                return 0;
            }
            var huanbi = Math.Round(((thisquarter - lastquarter) / (decimal)lastquarter), 4, MidpointRounding.AwayFromZero);
            if (thisquarter > lastquarter)
            {
                huanbi = Math.Abs(huanbi);
            }
            else
            {
                huanbi = -(Math.Abs(huanbi));
            }
            return Math.Round(huanbi * 100, 2, MidpointRounding.AwayFromZero);
        }

        public static decimal CalcJiaSu(decimal thisquarter, decimal lastquarter)
        {
            if (thisquarter == 0 || lastquarter == 0)
            {
                return 0;
            }
            var jiasudu = Math.Round((thisquarter - lastquarter) / lastquarter, 4, MidpointRounding.AwayFromZero);
            if (thisquarter > lastquarter)
            {
                jiasudu = Math.Abs(jiasudu);
            }
            else
            {
                jiasudu = -(Math.Abs(jiasudu));
            }
            return Math.Round(jiasudu * 100, 2, MidpointRounding.AwayFromZero);
        }

        public static (decimal, decimal, decimal, decimal) CalcMuBiaoJia(decimal curr, decimal last, decimal next, decimal low, decimal high)
        {
            var benRate = Math.Round((curr / last), 2, MidpointRounding.AwayFromZero);
            var bennianzuidi = Math.Round(benRate * low, 2, MidpointRounding.AwayFromZero);
            var bennianzuigao = Math.Round(benRate * high, 2, MidpointRounding.AwayFromZero);
            var xiaRate = Math.Round((next / curr), 2, MidpointRounding.AwayFromZero);
            var xianianzuidi = Math.Round(xiaRate * bennianzuidi, 2, MidpointRounding.AwayFromZero);
            var xianianzuigao = Math.Round(xiaRate * bennianzuigao, 2, MidpointRounding.AwayFromZero);
            return (bennianzuidi, bennianzuigao, xianianzuidi, xianianzuigao);
        }
        public static (decimal, decimal, decimal) CalcShiXiaoOrShiYing(decimal currshizhi, decimal curr, decimal last, decimal next)
        {
            decimal currData = curr == 0 ? 0 : Math.Round((currshizhi / curr), 2, MidpointRounding.AwayFromZero);
            decimal lastData = last == 0 ? 0 : Math.Round((currshizhi / last), 2, MidpointRounding.AwayFromZero);
            decimal nextData = next == 0 ? 0 : Math.Round((currshizhi / next), 2, MidpointRounding.AwayFromZero);
            return (currData, lastData, nextData);
        }
#if DEBUG
        public static decimal FinanceRate { get; set; } = 6.79M;
#elif RELEASE
        public static decimal FinanceRate { get; set; }
#endif
        public static async Task<decimal> GetFinanceRate(string FinanceA, string FinanceB)
        {
            if (FinanceRate > 0) return FinanceRate;
            //string apiAddress = $"http://api.k780.com/?app=finance.rate&scur={FinanceA}&tcur={FinanceB}&appkey=60860&sign=67c5e6bda37094bf53a8f01f70fef91f";
            string apiAddress = $"https://api.it120.cc/gooking/forex/rate?fromCode={FinanceB}&toCode={FinanceA}";
            using var client = new HttpClient();
            var response = await client.GetAsync(apiAddress);
            var responseJson = await response.Content.ReadAsStringAsync();
            var obj = responseJson.ToObject<dynamic>();
            FinanceRate = obj.data.rate;
            return FinanceRate;
        }
        public static decimal NumberConvert(string number)
        {
            if (number.Contains("B"))
            {
                return Convert.ToDecimal(number.Replace("B", "")) * 1000000000;
            }
            else if (number.Contains("M"))
            {
                return Convert.ToDecimal(number.Replace("M", "")) * 1000000;
            }
            return 0;
        }

    }

}
